﻿#region Imports

using System;
using System.Drawing;
using System.IO;
using System.Web;
using d3PrtDgn.Data.Domain.Entity;
using d3PrtDgn.Common.IService;

#endregion

namespace d3PrtDgn.Common.Service
{
	/// <summary>
	/// Photo manager for file http upload
	/// </summary>
	public class HttpPhotoManager : IPhotoManager
	{
		#region Constants

		public const float MAX_THUMB_SIZE = 150;
		public const float MAX_DETAIL_SIZE = 500;

		#endregion

		#region IPhotoManager members

		/// <summary>
		/// Uploads photo
		/// </summary>
		/// <param name="inputFile"><see cref="System.Web.HttpPostedFile"/> file</param>
		/// <param name="basePath">Base path for uploading</param>
		/// <returns>Uploaded photo</returns>
		public Photo Upload(object inputFile, string basePath)
		{
			return Upload(inputFile, basePath, string.Empty, string.Empty);
		}

		/// <summary>
		/// Uploads photo and creates thumbnail
		/// </summary>
		/// <param name="inputFile"><see cref="System.Web.HttpPostedFile"/> file</param>
		/// <param name="basePath">Base path for uploading</param>
		/// <param name="thumbPath">Path for thumbnails</param>
		/// <returns>Uploaded photo</returns>
		public Photo Upload(object inputFile, string basePath, string thumbPath)
		{
			return Upload(inputFile, basePath, thumbPath, string.Empty);
		}

		/// <summary>
		/// Uploads photo and creates thumbnail and detail
		/// </summary>
		/// <param name="inputFile"><see cref="System.Web.HttpPostedFile"/> file</param>
		/// <param name="basePath">Base path for uploading</param>
		/// <param name="thumbPath">Path for thumbnails</param>
		/// <param name="detailPath">Path for details</param>
		/// <returns>Uploaded photo</returns>
		public Photo Upload(object inputFile, string basePath, string thumbPath, string detailPath)
		{
			HttpPostedFile file;
			Photo photo = new Photo();

			// fill HttpPostedFile instance
			try { file = (HttpPostedFile)inputFile; }
			catch (Exception ex) { throw new ArgumentException("Input file is not in proper format", ex); }

			// fill photo properties
			FileInfo fileInfo = new FileInfo(file.FileName);
			photo.Filename = fileInfo.Name;
			photo.Filename = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds + "_" + photo.Filename; // make it somehow unique
			photo.Size = file.ContentLength;
			photo.Phototype = new Phototype(0, fileInfo.Extension, file.ContentType);

			// create directory if not exists
			if (!Directory.Exists(basePath))
			{
				Directory.CreateDirectory(basePath);
			}

			// create image
			Bitmap b = new Bitmap(file.InputStream);
			b.Save(Path.Combine(basePath, photo.Filename));

			if (thumbPath != string.Empty)
			{
				CreateThumbnail(b, thumbPath, photo.Filename, MAX_THUMB_SIZE);
			}

			if (detailPath != string.Empty)
			{
				CreateThumbnail(b, detailPath, photo.Filename, MAX_DETAIL_SIZE);
			}

			photo.Width = b.Width;
			photo.Height = b.Height;

			return photo;
		}

		#endregion

		#region Private methods

		/// <summary>
		/// Creates and saves thumbnails from photo
		/// </summary>
		/// <param name="original">Original photo</param>
		/// <param name="path">Store path</param>
		/// <param name="filename">Photo filename</param>
		/// <param name="size">Max width or height of photo</param>
		private static void CreateThumbnail(Image original, string path, string filename, float size)
		{
			// create directory if not exists
			if (!Directory.Exists(path))
			{
				Directory.CreateDirectory(path);
			}

			int targetH, targetW;
			if (original.Height > original.Width)
			{
				targetH = (int)size;
				targetW = (int)(original.Width * (size / original.Height));
			}
			else
			{
				targetW = (int)size;
				targetH = (int)(original.Height * (size / original.Width));
			}

			Image b = original.GetThumbnailImage(targetW, targetH, null, IntPtr.Zero);
			b.Save(Path.Combine(path, filename), original.RawFormat);
		}

		#endregion
	}
}
